package com.firegod.course.service;

import com.alibaba.fastjson.JSONObject;
import com.firegod.commonutils.result.ResultCode;
import com.firegod.servicebase.dao.*;
import com.firegod.servicebase.entity.*;
import com.firegod.servicebase.exceptionhandler.exception.GuliException;
import com.firegod.servicebase.service.BaseService;
import com.firegod.shiro.service.TokenService;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

@Service
public class CourseService extends BaseService<Course, Long, CourseRepository> {

    @Autowired
    private TeacherRepository teacherRepository;

    @Autowired
    private StudentRepository studentRepository;

    @Autowired
    private GroupRepository groupRepository;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private TokenService tokenService;

    @Autowired
    private VideoRepository videoRepository;

    @Autowired
    private ChapterRepository chapterRepository;

    public String createCourse(String title, String semester, String cover, String description, String tag) {
        String userIdWithType = tokenService.getCurrentUser();
        if (!userIdWithType.substring(0, 7).equalsIgnoreCase("teacher")) {
            throw GuliException.from(ResultCode.NOT_TEACHER);
        }
        String teacherId = userIdWithType.substring(9);
        String courseId = RandomStringUtils.randomAlphanumeric(16);
        while (baseRepository.getCourseByCourseId(courseId) != null) {
            courseId = RandomStringUtils.randomAlphanumeric(16);
        }
        Teacher teacher = teacherRepository.getByUserId(teacherId);
        Course course = new Course(teacher, courseId, title);
        if (semester != null) {
            course.setSemester(semester);
        }
        if (cover != null) {
            course.setCover(cover);
        }
        if (description != null) {
            course.setDescription(description);
        }
        if (tag != null) {
            course.setTag(tag);
        }
        //圈子
        Group group = new Group();

        group.setGroupId(courseId);
//        group.setCourse(course);
        groupRepository.save(group);
        course.setGroup(group);
        baseRepository.save(course);

        teacher.getCourseList().add(course);
        teacherRepository.saveAndFlush(teacher);
        return courseId;
    }

    public Map<String, Object> getCourseList(int limit, int offset) {
        HashMap<String, Object> hashMap = new HashMap<>();
        var result = baseRepository.findAll(PageRequest.of(offset, limit));
        long lastSize = result.getTotalElements();
        hashMap.put("courseList", result.getContent().stream().map(Course::show));
        hashMap.put("total", lastSize);
        return hashMap;
    }

    public HashMap<String, Object> getRecommendCourse(int limit) {
        HashMap<String, Object> hashMap = new HashMap<>();
        var result = baseRepository.findAll();
        long lastSize = Math.min(result.size(), limit);
        hashMap.put("courseList", result.stream().sorted(
                Comparator.comparing(Course::getNumOfStudent).reversed()
        ).limit(lastSize).map(Course::show));
        hashMap.put("total", lastSize);
        return hashMap;
    }

    public void deleteCourse(String courseId) {
        Course course = baseRepository.getCourseByCourseId(courseId);
        if (course == null) {
            throw GuliException.from(ResultCode.COURSE_NOT_EXIST);
        }
        baseRepository.delete(course);
    }

    public JSONObject getCourseById(String courseId, String userId) {
        Course course = baseRepository.getCourseByCourseId(courseId);
        User user = userRepository.getByUserId(userId);
        if (courseId == null) {
            throw GuliException.from(ResultCode.NO_COURSE_ID);
        }
        if (user == null) {
            return baseRepository.getCourseByCourseId(courseId).showDetail(false);
        }
        boolean join = false;
        if (user instanceof Student) {
            List<Student> students = course.getStudentList();
            System.out.println("course: " + course.getStudentList());
            for (var student : students) {
                if (student.getUserId().equals(userId)) {
                    join = true;
                    break;
                }
            }
        }
//        } else if (course.getTeacher().getUserId().equals(userId)) {
//            join = true;
//        }

        return baseRepository.getCourseByCourseId(courseId).showDetail(join);
    }

    public JSONObject[] importStudent(String courseId, List<Student> studentList) {
        String userIdWithType = tokenService.getCurrentUser();
        System.out.println(userIdWithType);
        if (!userIdWithType.substring(0, 7).equalsIgnoreCase("teacher")) {
            throw GuliException.from(ResultCode.NOT_TEACHER);
        }
        Teacher teacher = teacherRepository.getByUserId(userIdWithType.substring(9));
        Course course = baseRepository.getCourseByCourseId(courseId);
        if (course == null) {
            throw GuliException.from(ResultCode.COURSE_NOT_EXIST);
        }
        if (!teacher.getCourseList().contains(course)) {
            throw GuliException.from(ResultCode.COURSE_NOT_EXIST);
        }
        course.getStudentList().addAll(studentList);
        course.setStudentNumber(new AtomicInteger(course.getStudentList().size()));
        baseRepository.saveAndFlush(course);
        return studentList.stream().map(Student::show).toArray(JSONObject[]::new);
    }

    public JSONObject[] addStudent(String courseId, String userId, String name) {
        String userIdWithType = tokenService.getCurrentUser();
        System.out.println(userIdWithType);
        if (!userIdWithType.substring(0, 7).equalsIgnoreCase("teacher")) {
            throw GuliException.from(ResultCode.NOT_TEACHER);
        }
        Teacher teacher = teacherRepository.getByUserId(userIdWithType.substring(9));
        Course course = baseRepository.getCourseByCourseId(courseId);
        Student student;
        if (course == null) {
            throw GuliException.from(ResultCode.COURSE_NOT_EXIST);
        }
        if (!teacher.getCourseList().contains(course)) {
            throw GuliException.from(ResultCode.COURSE_NOT_EXIST);
        }
        User user = userRepository.getByUserId(userId);
        if (user instanceof Teacher) {
            throw GuliException.from("已存在此工号的老师，添加失败！");
        }
        if (user instanceof Student) {
            student = (Student) user;
            if (student.getName() == null) {
                student.setName(name);
                userRepository.save(student);
            }
        } else {
            student = new Student(userId, name);
            student.setPassword(DigestUtils.md5DigestAsHex("123456".getBytes(StandardCharsets.UTF_8)));
            userRepository.save(student);
        }
        course.getStudentNumber().getAndIncrement();
        List<Student> studentList = course.getStudentList();
        studentList.add(student);
        baseRepository.saveAndFlush(course);
        return studentList.stream().map(Student::show).toArray(JSONObject[]::new);
    }

    public Set<Course> getStudentCourses(String userId) {
        Student student = studentRepository.getByUserId(userId);
        return student.getCourseList();
    }

    public void editCourse(String courseId, String title, String semester, String cover, String description, String tag) {
        String userIdWithType = tokenService.getCurrentUser();
        if (!userIdWithType.substring(0, 7).equalsIgnoreCase("teacher")) {
            throw GuliException.from(ResultCode.NOT_TEACHER);
        }
        String teacherId = userIdWithType.substring(9);
        Teacher teacher = teacherRepository.getByUserId(teacherId);
        Course course = baseRepository.getCourseByCourseId(courseId);
        if (!teacher.getCourseList().contains(course)) {
            throw GuliException.from(ResultCode.COURSE_NOT_EXIST);
        }
        if (title != null) {
            course.setTitle(title);
        }
        if (semester != null) {
            course.setSemester(semester);
        }
        if (cover != null) {
            course.setCover(cover);
        }
        if (description != null) {
            course.setDescription(description);
        }
        if (tag != null) {
            course.setTag(tag);
        }
        baseRepository.saveAndFlush(course);
    }

    public JSONObject[] getStudentList(String courseId) {
        String userIdWithType = tokenService.getCurrentUser();
        if (!userIdWithType.substring(0, 7).equalsIgnoreCase("teacher")) {
            throw GuliException.from(ResultCode.NOT_TEACHER);
        }
        String teacherId = userIdWithType.substring(9);
        Teacher teacher = teacherRepository.getByUserId(teacherId);
        Course course = baseRepository.getCourseByCourseId(courseId);
        if (!teacher.getCourseList().contains(course)) {
            throw GuliException.from(ResultCode.COURSE_NOT_EXIST);
        }
        List<Student> studentList = course.getStudentList();
        return studentList.stream().map(Student::show).toArray(JSONObject[]::new);
    }

    public JSONObject addVideo(String courseId, Long chapterId, String title, String videoId) {
        String userIdWithType = tokenService.getCurrentUser();
        if (!userIdWithType.substring(0, 7).equalsIgnoreCase("teacher")) {
            throw GuliException.from(ResultCode.NOT_TEACHER);
        }
        String teacherId = userIdWithType.substring(9);
        Teacher teacher = teacherRepository.getByUserId(teacherId);
        Course course = baseRepository.getCourseByCourseId(courseId);
        if (!teacher.getCourseList().contains(course)) {
            throw GuliException.from(ResultCode.COURSE_NOT_EXIST);
        }
        if (title == null) {
            throw GuliException.from("请输入标题！");
        }
        Video video = new Video(title, videoId, "");
        List<Chapter> chapterList = course.getChapterList();
        Optional<Chapter> optionalChapter = chapterRepository.findById(chapterId);
        if (optionalChapter.isEmpty() || !chapterList.contains(optionalChapter.get())) {
            throw GuliException.from("章节不存在！");
        }
        Chapter chapter = optionalChapter.get();
        videoRepository.save(video);
        List<Video> videoList = chapter.getVideoList();
        if (videoList == null) {
            videoList = new ArrayList<>();
        }
        videoList.add(video);
        chapter.setVideoList(videoList);
        chapterRepository.saveAndFlush(chapter);
        return course.showChapterList();
    }

    public void joinCourse(String courseId) {
        String userIdWithType = tokenService.getCurrentUser();
        if (!userIdWithType.substring(0, 7).equalsIgnoreCase("student")) {
            throw GuliException.from(ResultCode.STUDENT_NOT_EXIST);
        }
        Student student = studentRepository.getByUserId(userIdWithType.substring(9));
        Course course = baseRepository.getCourseByCourseId(courseId);
        if (course == null) {
            throw GuliException.from(ResultCode.COURSE_NOT_EXIST);
        }
        List<Student> studentList = course.getStudentList();
        if (studentList.contains(student)) {
            throw GuliException.from("您已经加入此课程！");
        }
        studentList.add(student);
        course.getStudentNumber().getAndIncrement();
        baseRepository.saveAndFlush(course);
    }

    public void deleteVideo(String courseId, Long chapterId, String videoId) {
        Video video = videoRepository.findByVideoId(videoId);
        if (video == null) {
            throw GuliException.from("视频不存在！");
        }
        Optional<Chapter> chapterOptional = chapterRepository.findById(chapterId);
        if (chapterOptional.isEmpty()) {
            throw GuliException.from("章节不存在！");
        }
        Course course = baseRepository.getCourseByCourseId(courseId);
        if (course == null) {
            throw GuliException.from("课程不存在！");
        }
        Chapter chapter = chapterOptional.get();
        if (!course.getChapterList().contains(chapter)) {
            throw GuliException.from("章节不存在！");
        }
        if (!chapter.getVideoList().contains(video)) {
            throw GuliException.from("视频不存在！");
        }
        chapter.getVideoList().remove(video);
        videoRepository.delete(video);
        chapterRepository.saveAndFlush(chapter);
    }

    public void deleteStudent(String courseId, String userId) {
        Course course = baseRepository.getCourseByCourseId(courseId);
        Student student = studentRepository.getByUserId(userId);
        if (userId == null) {
            throw GuliException.from("学生不存在！");
        }
        if (course.getStudentList().remove(student)) {
            course.getStudentNumber().getAndDecrement();
        }
        baseRepository.saveAndFlush(course);
    }
}
